#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap/pcap.h>
#include <pcap.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "protocol.h"

#define BUFFER 2048

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define MAC_ARG(p) p[0],p[1],p[2],p[3],p[4],p[5]
#define IP_ARG(p)  p[0],p[1],p[2],p[3]


void indian_reverse(unsigned short arr[],int num)
{
	int i;
	unsigned short temp;

	for(i=0;i<num;i++)
	{
		temp = 0;

		temp = (arr[i]&0xff00)>>8;
		temp |= (arr[i]&0xff)<<8;
		arr[i] = temp;
	}
}

void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
	int i = 0;
	int *counter = (int *)arg;
	struct ethhdr *ethh;
	struct iphdr *iph;
	struct tcphdr *tcph;
	unsigned char *q;
	unsigned char *p = packet;
 
	ethh = (struct ethhdr *)p;	
	
#if 0
	printf("h_dest:%02x:%02x:%02x:%02x:%02x:%02x \n", MAC_ARG(ethh->h_dest));
	printf("h_source:%02x:%02x:%02x:%02x:%02x:%02x \n", MAC_ARG(ethh->h_source));
	printf("h_proto:%04x\n",ntohs(ethh->h_proto));
#endif
	/*
		解析以太头协议
	*/
	if(ntohs(ethh->h_proto) == 0x0800)
	{
	
		iph = (struct iphdr *)(p + sizeof(struct ethhdr));
#if 0
		q = (unsigned char *)&(iph->saddr);
		printf("src ip:%d.%d.%d.%d\n",IP_ARG(q));

		q = (unsigned char *)&(iph->daddr);
		printf("dest ip:%d.%d.%d.%d\n",IP_ARG(q));
#endif
		switch(iph->protocol)
		{
			case 0x1:
				//icmp
				break;
			case 0x6:
				//tcp				
				tcph = (struct tcphdr *)(p + sizeof(struct ethhdr) + sizeof(struct iphdr));
				if((tcph->ack == 1)&&(tcph->syn==1))
				{
					q = (unsigned char *)&(iph->saddr);
					printf("src ip:%d.%d.%d.%d ",IP_ARG(q));
					printf("\tsource:%d is avlible ,local port is dest:%d \n",ntohs(tcph->source),ntohs(tcph->dest));
				}
 
				break;
			case 0x11:
				//udp
				
				break;
		}	
	}	
	
 
	return;
	
}

int main(int argc,char *argv[])
{
	int	i = 0, count = 0;
	char	errbuf[PCAP_ERRBUF_SIZE];
	char	*device = NULL;
	char *ipstr="192.168.0.113";
	char cmd[128]={0};
	struct bpf_program filter;
	bpf_u_int32 netaddr = 0, mask = 0;

	memset(errbuf,0, sizeof(errbuf));
	//printf("error buffer size is :%d\n",PCAP_ERRBUF_SIZE);

	if(argc < 2){	
		fprintf(stderr,"Usage:%s ipaddr \a\n",argv[0]); 
		return -1;
	}else{
		ipstr = argv[1];
	}

	if((device = pcap_lookupdev(errbuf)) == NULL) {
		printf("pcap_lookupdev :%s\n",errbuf);
		return -1;
	}

	printf("found device: %s\n", device); 
	
	if (pcap_lookupnet(device, &netaddr, &mask, errbuf) == -1) {
		printf("pcap_lookupnet:%s\n",errbuf);
		return -1;
	}
	//printf("the netcode is :%s,", (char *)inet_ntoa(netaddr));
	//printf("the mask is :%s\n", (char *)inet_ntoa(mask));
	printf("netaddr:%08x\n",netaddr);
		
	printf("try to open device %s\n",device);
	pcap_t *descr = NULL;
	if((descr = pcap_open_live(device, BUFFER, 1, 0, errbuf)) == NULL) {
		printf("error:%s\n",errbuf);
		exit(-1);
	}
	sprintf(cmd,"host %s",ipstr);
	printf("filter:%s\n\n",cmd);
	//if(pcap_compile(descr,&filter,"arp and ether host 00:0c:29:80:1d:c0",0,mask) < 0)
	if(pcap_compile(descr,&filter,cmd,0,mask) == -1) {
		printf("pcap_compile error\n");
		exit(-1);
	}
	pcap_setfilter(descr,&filter);
	pcap_loop(descr,-1, processPacket, (u_char *)&count);
	printf("finished!\n");
	return 0;
}
